/*
 *	Copyright (c) 2009, libBasement
 *	All rights reserved.
 *	
 *	Redistribution and use in source and binary forms, with or without modification,
 *	are permitted provided that the following conditions are met:
 *	
 *	Redistributions of source code must retain the above copyright notice,
 *	this list of conditions and the following disclaimer.
 *	Redistributions in binary form must reproduce the above copyright notice,
 *	this list of conditions and the following disclaimer in the documentation
 *	and/or other materials provided with the distribution.
 *	Neither the name of the <ORGANIZATION> nor the names of its contributors may
 *	be used to endorse or promote products derived from this software without
 *	specific prior written permission.
 *	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 *	THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 *	FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef BGeometry_h
#define BGeometry_h 1

#include <BasementDefines.h>

namespace Basement
{
#if __LP64__ || BASEMENT_BUILD_32_LIKE_64
	typedef double Float;
#else
	typedef float Float;
#endif
	
	class Point
	{
	public:
		Float x;
		Float y;
		
		Point() : x(0.0), y(0.0) {}
		Point(Point &point) : x(point.x), y(point.y) {}
		Point(Float inX, Float inY) : x(inX), y(inY) {}
		
		Point operator+(Point &point) { return Point(this->x + point.x, this->y + point.y); }
		Point operator+=(Point &point) { this->x += point.x; this->y += point.y; return this; }
		Point operator-(Point &point) { return Point(this->x - point.x, this->y - point.y); }
		Point operator-=(Point &point) { this->x -= point.x; this->y -= point.y; return this; }
		Point operator*(Point &point) { return Point(this->x * point.x, this->y * point.y); }
		Point operator*=(Point &point) { this->x *= point.x; this->y *= point.y; return this; }
		Point operator/(Point &point) { return Point(this->x / point.x, this->y / point.y); }
		Point operator/=(Point &point) { this->x /= point.x; this->y /= point.y; return this; }
		
		bool operator==(Point &point) { return (this->x == point.x) && (this->y == point.y); }
		bool operator!=(Point &point) { return !this->operator==(point); }
	};
	
	class Size
	{
	public:
		Float width;
		Float height;
		
		Size() : width(0.0), height(0.0) {}
		Size(Size &point) : width(point.width), height(point.height) {}
		Size(Float inWidth, Float inHeight) : width(inWidth), height(inHeight) {}
		
		Size operator+(Size &point) { return Size(this->width + point.width, this->height + point.height); }
		Size operator+=(Size &point) { this->width += point.width; this->height += point.height; return this; }
		Size operator-(Size &point) { return Size(this->width - point.width, this->height - point.height); }
		Size operator-=(Size &point) { this->width -= point.width; this->height -= point.height; return this; }
		Size operator*(Size &point) { return Size(this->width * point.width, this->height * point.height); }
		Size operator*=(Size &point) { this->width *= point.width; this->height *= point.height; return this; }
		Size operator/(Size &point) { return Size(this->width / point.width, this->height / point.height); }
		Size operator/=(Size &point) { this->width /= point.width; this->height /= point.height; return this; }
		
		bool operator==(Size &point) { return (this->width == point.width) && (this->height == point.height); }
		bool operator!=(Size &point) { return !this->operator==(point); }
	};
	
	class Rect
	{
	public:
		Point origin;
		Size size;
		
		Rect() {}
		Rect(Point point, Size inSize) : origin(point), size(inSize) {}
		Rect(Float x, Float y, Float width, Float height) : origin(x, y), size(width, height) {}
		
		bool operator==(Rect &rect) { return (this->origin == rect.origin) && (this->size == rect.size); }
		bool operator!=(Rect &rect) { return !this->operator==(rect); }
	};
}

#endif /* BGeometry_h */
